<?php
/**
 * Copyright (c) 2011 by Bohdan Padalko <bohdan.padalko@gmail.com>
 * All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE. */


include 'lib.event.php';

// + Add r.type (relation type) key to rels description
// + Add item status property, r/o $item->getStatus()
// * Change DbItem initialization behavior (binded relations are initialized with it's parent props)

// TODO: CREATE, UPDATE, DELETE items, also in relations

// TODO: notify relation on it's key change

// TODO: document r.type !!! <- relation type, see R_* constants

// XXX: maybe move all selects, etc. in Query object and SimpleQuery will become Collection object?

// TODO: cleanup
// TODO: abstractions level cleanup
// TODO: make events work!
// TODO: write support
// TODO: unit testing, database test schema
// TODO: work on relational subsystem
// TODO: Makes constatns to be integer


// ExTodo: possible optimization to init methods as static : no sense at all.

class TH_DbBase {
    const L_ALL = 'L_ALL';    // load all data
    const L_REQ = 'L_REQ';    // load requested data

    const T_BOOL         = 'T_BOOL';
    const T_INT          = 'T_INT';
    const T_FLOAT        = 'T_FLOAT';
    const T_STRING       = 'T_STRING';
    const T_SERIALIZABLE = 'T_SERIALIZABLE';
    const T_RELATION     = 'T_RELATION';    // NOTE: for internal use
    const T_VIRTUAL      = 'T_VIRTUAL';     // NOTE: for internal use

    const A_DENIED   = 'A_DENIED';
    const A_READONLY = 'A_READONLY';
    const A_FULL     = 'A_FULL';

    const D_STORAGE = 'D_STORAGE';
    const D_BROKER  = 'D_BROKER';

    const S_READY    = 'S_READY';    // TODO: replace with int values in release
    const S_COUNT    = 'S_COUNT';
    const S_LOADED   = 'S_LOADED';
    const S_MODIFIED = 'S_MODIFIED';

    const R_AUTO       = 'R_AUTO';
    const R_DIRECT     = 'R_DIRECT';
    const R_BACK       = 'R_BACK';
    const R_BROKER     = 'R_BROKER';


	/**
	 * Database handler
	 * @var PDO
	 */
	private $tdb;

	/**
	 * @var array
	 */
	private $loaded_tables = array();

	public function __construct(PDO &$tdb) {
		$this->tdb = $tdb;
	}

    public function prepare ($statement, array $driver_options = array()) {
	    return $this->tdb->prepare($statement, $driver_options);
	}

	/**
	 * Remove TH_DbSimpleQuery from $loaded_tables, so now when we call next
	 * time for $name table it will be another object. In this way we can have
	 * two tables at the same time.
	 *
	 * @param string $name
	 * 		Table name to detach
	 */
	public function detach($name) {
	    $r =$this->loaded_tables[$name];
	    unset($this->loaded_tables[$name]);
        return $r;
	}

	function __get($name) {
	    if (!array_key_exists($name, $this->loaded_tables)) {
	        $this->loaded_tables[$name] = new TH_DbSimpleQuery($this, $name);
	    }

        return $this->loaded_tables[$name];
	}


	public function __set($prop, $value) {
	    throw new Exception("Not allowed");
	}
}






?>
